(function (angular) {
    'use strict';
    var storageModule = angular.module("fs.storage")
    storageModule.provider('storageService', storageService);
    storageService.$inject = ['StorageConstants'];
    function storageService(StorageConstants) {
        var privoder = this;
        privoder.logStorageSize = 2000;
        privoder.searchCriteriaStorageSize = 20;
        privoder.searchCriteriaStorageMinutes = 5;
        privoder.hisStorageSize = 200;
        privoder.setLogStorageSize = function (size) {
            privoder.logStorageSize = size;
        };
        privoder.getLogStorageSize = function () {
            return privoder.logStorageSize;
        };
        privoder.setSearchCriteriaStorageSize = function (size) {
            privoder.searchCriteriaStorageSize = size;
        };
        privoder.getSearchCriteriaStorageSize = function () {
            return privoder.searchCriteriaStorageSize;
        };
        privoder.setSearchCriteriaStorageMinutes = function (minutes) {
            privoder.searchCriteriaStorageMinutes = minutes;
        };
        privoder.getSearchCriteriaStorageMinutes = function () {
            return privoder.searchCriteriaStorageMinutes;
        };
        privoder.setHisStorageSize = function (size) {
            privoder.hisStorageSize = size;
        };
        privoder.getHisStorageSize = function () {
            return privoder.hisStorageSize;
        };

        this.$get = ['$injector', 'localStorageService', '$filter', function ($injector, localStorageService, $filter) {
            privoder.localStorageService = localStorageService;
            return {
                clearAllFromSession: clearAllFromSession,
                clearAllFromLocal: clearAllFromLocal,
                clearAllCookie: clearAllCookie,
                setCookie: setCookie,
                getCookie: getCookie,
                removeCookie: removeCookie,
                removeItemFromSession: removeItemFromSession,
                removeItemFromLocal: removeItemFromLocal,
                setItemToSession: setItemToSession,
                getItemFromSession: getItemFromSession,
                setItemToLocal: setItemToLocal,
                getItemFromLocal: getItemFromLocal,
                setLogStorageSize: privoder.setLogStorageSize,
                getLogStorageSize: privoder.getLogStorageSize,
                saveLog: saveLog,
                getLog: getLog,
                saveSearchCriteria: saveSearchCriteria,
                getSearchCriteria: getSearchCriteria,
                saveSiteInfo: saveSiteInfo,
                getSiteInfo: getSiteInfo,
                saveUserInfo: saveUserInfo,
                getUserInfo: getUserInfo,
                saveFormatInfo: saveFormatInfo,
                getFormatInfo: getFormatInfo,
                saveSystemInfo: saveSystemInfo,
                getSystemInfo: getSystemInfo,
                saveMenuInfo: saveMenuInfo,
                getMenuInfo: getMenuInfo,
                saveMenuConfigInfo: saveMenuConfigInfo,
                getMenuConfigInfo: getMenuConfigInfo,
                saveHistory: saveHistory,
                popHistory: popHistory,
                getLastHistory: getLastHistory,
                getSystemSettings: getSystemSettings,
                saveSystemSettings: saveSystemSettings,
                saveDbdPanelSetting: saveDbdPanelSetting,
                getDbdPanelSetting: getDbdPanelSetting,
                saveTableSetting: saveTableSetting,
                getTableSetting: getTableSetting
            };
            function clearAllCookie() {
                privoder.localStorageService.cookie.clearAll();
            }

            function getCookie(key) {
                return privoder.localStorageService.cookie.get(key);
            }

            function setCookie(key, value, daysToExpiry, secure) {
                privoder.localStorageService.cookie.set(key, value, daysToExpiry, secure);
            }

            function removeCookie(key) {
                privoder.localStorageService.cookie.clearAll();
            }

            function clearAllFromSession(type) {
                privoder.localStorageService.clearAll(null, 'sessionStorage');
            }

            function clearAllFromLocal(type) {
                privoder.localStorageService.clearAll(null, 'localStorage');
            }

            function removeItemFromSession(key) {
                privoder.localStorageService.remove(key, 'sessionStorage');
            }

            function removeItemFromLocal(key) {
                privoder.localStorageService.remove(key, 'localStorage');
            }

            function setItemToSession(key, value) {
                privoder.localStorageService.set(key, value, 'sessionStorage');
            }

            function getItemFromSession(key) {
                return privoder.localStorageService.get(key, 'sessionStorage');
            }

            function setItemToLocal(key, value) {
                privoder.localStorageService.set(key, value, 'localStorage');
            }

            function getItemFromLocal(key) {
                return privoder.localStorageService.get(key, 'localStorage');
            }

            function saveLog(logContent) {
                if (!logContent)
                    return;
                var log = getLog();
                if (log.length < privoder.getLogStorageSize()) {
                    log.push(logContent);
                } else {
                    log.shift();
                    log.push(logContent);
                }
                setItemToSession(StorageConstants.LOG_STORAGE_KEY, angular.toJson(log));
            }

            function getLog() {
                var logContent = getItemFromSession(StorageConstants.LOG_STORAGE_KEY) || "[]";
                return angular.fromJson(logContent);
            }

            function saveSearchCriteria(searchCriteria) {
                var i, searchCriteriaList;
                if (searchCriteria) {
                    searchCriteria = angular.copy(searchCriteria);
                    searchCriteriaList = getSearchCriteriaList();
                    for (i = 0; i < searchCriteriaList.length; i++) {
                        if (searchCriteriaList[i].$state == searchCriteria.$state) {
                            searchCriteria._storageDate = new Date().getTime();
                            formatDate(searchCriteria);
                            searchCriteriaList[i] = searchCriteria;
                            setItemToSession(StorageConstants.SEARCH_CRITERIA_STORAGE_KEY, angular.toJson(searchCriteriaList));
                            delete searchCriteria._storageDate;
                            break;
                        }
                    }
                    if (i < searchCriteriaList.length)
                        return;
                    if (searchCriteriaList.length < privoder.getSearchCriteriaStorageSize()) {
                        searchCriteria._storageDate = new Date().getTime();
                        formatDate(searchCriteria);
                        searchCriteriaList.push(searchCriteria);
                    } else {
                        searchCriteriaList.shift();
                        searchCriteria._storageDate = new Date().getTime();
                        formatDate(searchCriteria);
                        searchCriteriaList.push(searchCriteria);
                    }
                    setItemToSession(StorageConstants.SEARCH_CRITERIA_STORAGE_KEY, angular.toJson(searchCriteriaList));
                    delete searchCriteria._storageDate;
                }
            }

            function getSearchCriteriaList() {
                var i, searchCriteriaList = getItemFromSession(StorageConstants.SEARCH_CRITERIA_STORAGE_KEY);
                searchCriteriaList = angular.fromJson(searchCriteriaList) || [];
                for (i = 0; i < searchCriteriaList.length; i++) {
                    parseDate(searchCriteriaList[i]);
                }
                return searchCriteriaList;
            }

            function getSearchCriteria(state) {
                var i, searchCriteriaList;
                if (!state) {
                    return undefined;
                }
                searchCriteriaList = getSearchCriteriaList();
                for (i = 0; i < searchCriteriaList.length; i++) {
                    if (searchCriteriaList[i].$state == state) {
                        if (searchCriteriaList[i]._storageDate < (new Date().getTime() - privoder.searchCriteriaStorageMinutes * 60 * 1000)) {
                            return undefined;
                        };
                        delete searchCriteriaList[i]._storageDate;
                        return searchCriteriaList[i];
                    }
                }
            }

            function saveSiteInfo(siteInfo) {
                var formatService, formatInfo;
                if (siteInfo) {
                    formatService = $injector.get('formatService');
                    formatInfo = getFormatInfo();
                    siteInfo.bizDate = formatService.formatDate(siteInfo.bizDate, formatInfo.longTimestamp);
                    siteInfo.cutoffTime = formatService.formatDate(siteInfo.cutoffTime, formatInfo.longTimestamp);
                    siteInfo.eodDate = formatService.formatDate(siteInfo.eodDate, formatInfo.longTimestamp);
                    setItemToSession(StorageConstants.SITE_INFO_STORAGE_KEY, angular.toJson(siteInfo));
                }
            }

            function getSiteInfo() {
                var formatService, formatInfo, siteInfo = getItemFromSession(StorageConstants.SITE_INFO_STORAGE_KEY) || "{}";
                siteInfo = angular.fromJson(siteInfo);
                if (siteInfo) {
                    formatService = $injector.get('formatService');
                    formatInfo = getFormatInfo();
                    siteInfo.bizDate = formatService.parseDate(siteInfo.bizDate, formatInfo.longTimestamp);
                    siteInfo.cutoffTime = formatService.parseDate(siteInfo.cutoffTime, formatInfo.longTimestamp);
                    siteInfo.eodDate = formatService.parseDate(siteInfo.eodDate, formatInfo.longTimestamp);
                }
                return siteInfo;
            }

            function saveSystemInfo(systemInfo) {
                if (systemInfo)
                    setItemToSession(StorageConstants.SYSTEM_INFO_STORAGE_KEY, angular.toJson(systemInfo));
            }

            function getSystemInfo() {
                var systemInfo = getItemFromSession(StorageConstants.SYSTEM_INFO_STORAGE_KEY) || "{}";
                return angular.fromJson(systemInfo);
            }

            function saveUserInfo(userInfo) {
                if (userInfo)
                    setItemToSession(StorageConstants.USER_INFO_STORAGE_KEY, angular.toJson(userInfo));
            }

            function getUserInfo() {
                var userInfo = getItemFromSession(StorageConstants.USER_INFO_STORAGE_KEY) || "{}";
                return angular.fromJson(userInfo);
            }

            function saveFormatInfo(formatInfo) {
                if (formatInfo)
                    setItemToSession(StorageConstants.FORMAT_INFO_STORAGE_KEY, angular.toJson(formatInfo));
            }

            function getFormatInfo() {
                var formatInfo = getItemFromSession(StorageConstants.FORMAT_INFO_STORAGE_KEY) || "{}";
                return angular.fromJson(formatInfo);
            }

            function saveMenuInfo(menuInfo) {
                if (menuInfo)
                    setItemToSession(StorageConstants.MENU_INFO_STORAGE_KEY, angular.toJson(menuInfo));
            }

            function getMenuInfo() {
                var menuInfo = getItemFromSession(StorageConstants.MENU_INFO_STORAGE_KEY) || "[]";
                return angular.fromJson(menuInfo);
            }

            function saveMenuConfigInfo(menuInfo) {
                if (menuInfo)
                    setItemToSession(StorageConstants.MENU_CONFIG_INFO_STORAGE_KEY, angular.toJson(menuInfo));
            }

            function getMenuConfigInfo() {
                var menuInfo = getItemFromSession(StorageConstants.MENU_CONFIG_INFO_STORAGE_KEY) || "[]";
                return angular.fromJson(menuInfo);
            }

            function saveDbdPanelSetting(pagePanelId, setting) {
                pagePanelId = $filter('encode')(pagePanelId);
                var userInfo = getUserInfo();
				/*var panelSetting = getDbdPanelSetting(pagePanelId);
				angular.merge(panelSetting, setting);*/
                setting.id = userInfo.userId + ":" + userInfo.workingCompanyCode + ':' + pagePanelId;
                saveDbdPanelConfig(setting);
            }

            function getDbdPanelSetting(pagePanelId) {
                pagePanelId = $filter('encode')(pagePanelId);
                var panelSettings = getItemFromLocal(StorageConstants.DBD_PANEL_KEY) || "{}";
                var userInfo = getUserInfo();
                panelSettings = angular.fromJson(panelSettings);
                return (panelSettings[userInfo.userId + ":" + userInfo.workingCompanyCode + ':' + pagePanelId] || panelSettings[userInfo.userId + ":" + userInfo.homeCompanyCode + ':' + pagePanelId]) || {};
            }

            function saveDbdPanelConfig(setting) {
                var panelSettings = getItemFromLocal(StorageConstants.DBD_PANEL_KEY) || "{}";
                panelSettings = angular.fromJson(panelSettings);
                panelSettings[setting.id] = setting;
                setItemToLocal(StorageConstants.DBD_PANEL_KEY, angular.toJson(panelSettings));
            }

            function saveTableSetting(tableId, setting) {
                var userInfo = getUserInfo();
                var tableSetting = getTableSetting(tableId);
                if (setting.visible) {
                    if (tableSetting.visible) {
                        angular.merge(tableSetting.visible, setting.visible);
                    } else {
                        tableSetting.visible = setting.visible;
                    }
                }
                tableSetting.displayStyle = setting.displayStyle || tableSetting.displayStyle;
                tableSetting.order = setting.order || tableSetting.order;
                if (setting.width) {
                    if (tableSetting.width) {
                        angular.merge(tableSetting.width, setting.width);
                    } else {
                        tableSetting.width = setting.width;
                    }
                }
                tableSetting.id = userInfo.userId + ':' + tableId;
                saveTableConfig(tableSetting);
            }

            function getTableSetting(tableId) {
                var tableSettings = getItemFromLocal(StorageConstants.TABLE_KEY) || "{}";
                var userInfo = getUserInfo();
                tableSettings = angular.fromJson(tableSettings);
                return tableSettings[userInfo.userId + ':' + tableId] || {};
            }

            function saveTableConfig(setting) {
                var tableSettings = getItemFromLocal(StorageConstants.TABLE_KEY) || "{}";
                tableSettings = angular.fromJson(tableSettings);
                tableSettings[setting.id] = setting;
                setItemToLocal(StorageConstants.TABLE_KEY, angular.toJson(tableSettings));
            }

            function saveHistory(historyObj) {
                var histories = getItemFromSession(StorageConstants.BACKHIS_STORAGE_KEY) || "[]";
                histories = angular.fromJson(histories);
                if (histories.length < privoder.getHisStorageSize()) {
                    histories.push(historyObj);
                } else {
                    histories.shift();
                    histories.push(historyObj);
                }
                setItemToSession(StorageConstants.BACKHIS_STORAGE_KEY, angular.toJson(histories));
            }

            function popHistory() {
                var history, histories = getItemFromSession(StorageConstants.BACKHIS_STORAGE_KEY) || "[]";
                histories = angular.fromJson(histories);
                if (histories && histories.length > 0) {
                    history = histories.pop();
                    setItemToSession(StorageConstants.BACKHIS_STORAGE_KEY, angular.toJson(histories));
                }
                return history;
            }

            function getLastHistory() {
                var history, histories = getItemFromSession(StorageConstants.BACKHIS_STORAGE_KEY) || "[]";
                histories = angular.fromJson(histories);
                if (histories && histories.length > 0) {
                    history = histories[histories.length - 1];
                }
                return history;
            }

            function getSystemSettings() {
                var settings = getItemFromLocal(StorageConstants.SYSTEM_SETTINGS_KEY);
                return angular.fromJson(settings);
            }

            function saveSystemSettings(settings) {
                if (settings) {
                    setItemToLocal(StorageConstants.SYSTEM_SETTINGS_KEY, angular.toJson(settings));
                }
            }
            function formatDate(object) {
                var formatter = getFormatInfo().longTimestamp;
                var formatService = $injector.get('formatService');
                function format(object) {
                    angular.forEach(object, function (value, key) {
                        if (!object.hasOwnProperty(key))
                            return;
                        if (angular.isDate(value)) {
                            object[key] = formatService.formatDate(value, formatter);
                        } else if (angular.isObject(value)) {
                            format(value);
                        }
                    });
                }
                format(object);
                return object;
            }
            function parseDate(object) {
                var formatter = getFormatInfo().longTimestamp;
                var formatService = $injector.get('formatService');
                var fsDatePattern = new RegExp(formatter.replace('.', '\\.').replace(/[ydhHMmsS]/g, '\\d').replace(/Z/g, '[-+]\\d{4}'));
                function parse(object) {
                    angular.forEach(object, function (value, key) {
                        if (!object.hasOwnProperty(key))
                            return;
                        if (angular.isString(value) && fsDatePattern.test(value)) {
                            object[key] = formatService.parseDate(value, formatter);
                        } else if (angular.isObject(value)) {
                            parse(value);
                        }
                    });
                }
                parse(object);
                return object;
            }
        }];

    }
})(angular);